////////////////////////////////////////////////////////////////////////////////
//
//  MICROSOFT CORPORATION
//  Copyright (c) Microsoft Corporation.
//  All Rights Reserved.
//
//  NOTICE: Microsoft Confidential. Intended for Internal Use Only.
//
////////////////////////////////////////////////////////////////////////////////

package com.msn.beet.utils
{

import com.msn.beet.core.StaticClass;

/**
 * A memoized function "remembers" the results corresponding to some set of
 * specific inputs. Subsequent calls with remembered inputs return the
 * remembered result rather than recalculating it, thus moving the primary
 * cost of a call with given parameters to the first call made to the
 * function with those parameters.
 *
 * cf. http://en.wikipedia.org/wiki/Memoization
 *
 */
public class MemoizedFunctor extends StaticClass
{
    include "../core/Version.as";

    /**
     * Construct the memoized functor
     *
     * @param scope object scope, if any, to apply the function to
     * @param func the function to be memoized
     * @return a functor that can be called to retrieve the returned value
     * without incurring the processor overhead of re-running the function
     *
     */
    public static function construct(scope:*, func:Function):Function
    {
        var hash:Object = {};
        var newFunctor:Function = function(... rest):*
        {
            var key:String = rest.join(",");
            var result:* = hash[key];

            if (result == null)
            {
                result = func.apply(scope, rest);
                hash[key] = result;
            }

            return result;
        }

        return newFunctor;
    }
}

}
